package com.zj.musicTools.function

import android.content.ContentUris
import android.content.Context
import android.database.Cursor
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.DocumentsContract
import android.provider.MediaStore
import android.service.controls.ControlsProviderService.TAG
import android.util.Log
import com.zj.musicTools.MainActivity.Companion.CONTEXT
import com.zj.musicTools.function.SQLwriter.Companion.configData
import java.io.File

/**
 * 遍历目录子项，若子项是目录文件则 执行task(String)回调该文件路径
 * */
private fun traverseFileTreeOneLevel(file: File,task:((File) -> Unit)?) {
    try {
        file.listFiles()?.let { children ->
            children.forEach { child ->
                if (child.isDirectory) {
                    task?.let{ it(child) }
                }
            }
        }
    }catch (e:Exception){
        Log.e("traverseFileTreeOneLevel()",e.toString())
    }
}

class AppPath {
    private val logfile= getDiskCachePath(CONTEXT).toString()+ "/daily.log"//获取缓存目录
    private lateinit var InputFilePath:Uri
    private lateinit var customDir:String
    var netease:String? = null
    var kugou:String? = null
    var kuwo:String? = null
    var qqmusic:String? = null

    var input:String? = null //从页面的设置中获取
    var output:String? = null

    init {
        netease = netease()
        kugou=kugou()
        qqmusic=qqmusic()
        kuwo = kuwo()
        inputInit()
        outputInit()
    }

    private fun inputInit(){
        val inputConfig=configData.get("DefInputPath")
        input=
            when(inputConfig){
                "自定义"->{
                    configData.get("CustomPath")?:""
                }
                "上次使用"->{
                    configData.get("LastPath")?:""
                }
                "网易云"->{
                    netease?:""
                }
                "酷狗" ->{
                    kugou?:""
                }
                "QQ音乐"->{
                    qqmusic?:""
                }
                "酷我"->{
                    kuwo?:""
                }

                else -> {""}
            }
    }
    private fun outputInit(){
        val outputConfig=configData.get("DefOutputPath")
        output=
            when(outputConfig){
                "原路径"->{
                    input?:""
                }
                "自定义"->{
                    configData.get("CustomPath")?:""
                }
                "上次使用"->{
                    configData.get("LastPath")?:""
                }
                "网易云"->{
                    netease?:""
                }
                "酷狗" ->{
                    kugou?:""
                }
                "QQ音乐"->{
                    qqmusic?:""
                }
                "酷我"->{
                    kuwo?:""
                }

                else -> {""}
            }
    }


    fun search(dir:File,keywork:String,task:((File) -> Unit)?) {
        traverseFileTreeOneLevel(dir) { file ->
            if (file.name.contains(keywork, ignoreCase = true)) {
                task?.let { it(file) }
            } else
                search(file, keywork, task) //找不到继续从下级目录找
        }
        Log.i("search()","keyword:$keywork")

    }


    /**
     * 查找网易云音乐路径
     * */
    private fun netease(): String? {
        var searchPath: String? =null
        val rooter= File(rootPath()?:"")
        if(rooter.exists())
            search(rooter, "netease"){
                search(it,"cloudmusic"){
                    cloudmusicPath->
                    searchPath = cloudmusicPath.absolutePath + "/Music/"
                }
            }
        return searchPath
    }

    private fun qqmusic(): String? {
        var searchPath: String? =null
        val rooter= File(rootPath()?:"")
        if(rooter.exists())
            search(rooter, "qqmusic"){
                search(it,"song"){
                        cloudmusicPath->
                    searchPath = cloudmusicPath.absolutePath
                }
            }
        return searchPath
    }

    private fun kuwo(): String? {
        var searchPath: String? =null
        val rooter= File(rootPath()?:"")
        if(rooter.exists())
            search(rooter, "kuwomusic"){
                search(it,"music"){
                        kuwoPath->
                    searchPath = kuwoPath.absolutePath
                }
            }
        return searchPath
    }

    private fun kugou(): String? {
        var searchPath: String? =null
        val rooter= File(rootPath()?:"")
        if(rooter.exists())
            search(rooter, "KuGouLite"){//酷狗概念版
                search(it,"Music"){
                        kugouPath->
                    searchPath = kugouPath.absolutePath
                }
            }
        if(searchPath.isNullOrEmpty())
            search(rooter, "kgmusic"){
                search(it,"download"){
                        kugouPath->
                    searchPath = kugouPath.absolutePath
                }
            }

        return searchPath
    }


    /**
     * 获取或更新输入文件地址
     *
     * */
    fun input(uri:Uri?=null): String {
        if(uri==null) return UriToPath(CONTEXT,InputFilePath)
        else InputFilePath=uri
        return ""
    }

    fun UriToPath(context:Context?,inUri: Uri?): String {

        if (context == null || inUri == null)
            return ""
        if (/**此项目限制运行环境大于安卓5.0所以无需判断 android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT &&*/
            DocumentsContract.isDocumentUri(context, inUri) ) {//context用于访问系统服务模块，判断URI是否为文档
            if (isExternalStorageDocument(inUri)) {
                val docId:String = DocumentsContract.getDocumentId(inUri)
                val split = docId.split(":")
                val type:String = split[0]
                if ("primary".equals(type)) {
                    return Environment.getExternalStorageDirectory().path + "/" + split[1]
                }
            } else if (isDownloadsDocument(inUri)) {
                val id:String = DocumentsContract.getDocumentId(inUri)
                val contentUri: Uri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), id.toLong())
                return getDataColumn(context, contentUri, null, null)
            } else if (isMediaDocument(inUri)) {
                val docId:String = DocumentsContract.getDocumentId(inUri)
                val split = docId.split(":")
                val type:String = split[0]
                var contentUri: Uri?=null
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
                }
                val selection = MediaStore.Images.Media._ID + "=?"
                val selectionArgs:Array<String> = arrayOf(split[1])
                return contentUri.let { getDataColumn(context, it!!, selection, selectionArgs) }
            }
        } // MediaStore (and general)
        else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N &&
            DocumentsContract.isTreeUri(inUri) ){
            if (isExternalStorageDocument(inUri)) {
                val docId:String = DocumentsContract.getTreeDocumentId(inUri)
                val split = docId.split(":")
                val type:String = split[0]
                if ("primary".equals(type)) {
                    return Environment.getExternalStorageDirectory().path + "/" + split[1]+"/"
                }
            }else if (isDownloadsDocument(inUri)) {
                val id:String = DocumentsContract.getTreeDocumentId(inUri)
                val contentUri: Uri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), id.toLong())
                return getDataColumn(context, contentUri, null, null)
            } else if (isMediaDocument(inUri)) {
                val docId:String = DocumentsContract.getTreeDocumentId(inUri)
                val split = docId.split(":")
                val type:String = split[0]
                var contentUri: Uri?=null
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
                }
                val selection = MediaStore.Images.Media._ID + "=?"
                val selectionArgs:Array<String> = arrayOf(split[1])
                return contentUri.let { getDataColumn(context, it!!, selection, selectionArgs) }
            }
        }// Directory
        else if ("content".equals(inUri.scheme)) {
            // Return the remote address
            if (isGooglePhotosUri(inUri))
                return inUri.lastPathSegment.toString()
            return getDataColumn(context, inUri, null, null)
        }
        // File
        else if ("file".equals(inUri.scheme)) {
            return inUri.path.toString()
        }
        return ""
    }

    fun getDiskCachePath(context: Context): String? {
        return if (Environment.MEDIA_MOUNTED == Environment.getExternalStorageState() || !Environment.isExternalStorageRemovable()) {
            context.externalCacheDir?.path
        } else {
            context.cacheDir.path
        }
    }

    /**
     * 从本地设备数据库查询数据.
     *
     * @param context       上下文
     * @param uri           内容提供者的标识
     * @param selection     设置条件，相当于SQL语句中的where
     * @param selectionArgs 条件值
     * @return 查询结果
     */
    private fun getDataColumn(context:Context, uri: Uri, selection: String?, selectionArgs: Array<String>?): String {
        var cursor: Cursor? =null
        val column:String = MediaStore.Images.Media.DATA
        val projection:Array<String> = arrayOf(column)  //告诉Provider要返回的内容（列Column）
        try {
            cursor =
                context.contentResolver.query(uri, projection, selection, selectionArgs, null)!!

            if (cursor.moveToFirst()) {
                val index:Int = cursor.getColumnIndexOrThrow(column)
                return cursor.getString(index)
            }
        } finally {
            cursor?.close()
        }
        return ""
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     */
    private fun isExternalStorageDocument(uri: Uri) :Boolean {
        return "com.android.externalstorage.documents".equals(uri.authority)
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     */
    private fun isDownloadsDocument(uri: Uri) :Boolean{
        return "com.android.providers.downloads.documents".equals(uri.authority)
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     */
    private fun  isMediaDocument(uri: Uri) :Boolean{
        return "com.android.providers.media.documents".equals(uri.authority)
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is Google Photos.
     */
    private fun isGooglePhotosUri( uri: Uri):Boolean {
        return "com.google.android.apps.photos.content".equals(uri.authority)
    }
    fun rootPath(pathInternal:Boolean=true): String? {
//        val pathFlag = true
        return try {
            var rootPath: String?
            if (pathInternal) {
//                Log.d(TAG, "getRootPath: 正在获取内置SD卡根目录")
                rootPath = Environment.getExternalStorageDirectory().toString()
                Log.d(TAG, "getRootPath: 内置SD卡目录为:$rootPath")
                rootPath
            } else {
//                Log.d(TAG, "getRootPath: 正在获取外置SD卡根目录")
                rootPath = System.getenv("SECONDARY_STORAGE")
                if (rootPath == Environment.getExternalStorageDirectory().toString())
                    rootPath = null
                Log.d(TAG,"getRootPath:  外置SD卡路径为：$rootPath")
                rootPath
            }
        } catch (e: Exception) {
            Log.e("getRootPath", e.toString())
            null
        }
    }
    fun readTextFromFile(filePath: String): String {
        val file = File(filePath)
        return file.readText()
    }


    fun logPath(): String {
        return logfile
    }

    private fun String.getBeforeDir() : String{
        return try {
            var pathbuf = this
            var file= File(this)

            if(file.isFile){//若输入为文件名，去掉文件名
                pathbuf=pathbuf.take(pathbuf.lastIndexOf("/")) //取路径
                file= File(pathbuf)
            }
            if(!file.isFile){ //若是路径名称，先检查路径是否存在，不存在则新建路径
                pathbuf=pathbuf.take(pathbuf.lastIndexOf("/")) //取路径
//                if(!file.exists()) file.mkdir()
            }
            pathbuf
        }catch (e:Exception){
            this
        }
    }

    fun getSetPath():String{
        val path=CONTEXT.externalCacheDir!!.path.getBeforeDir()+"/set"
        val file= File(path)
        if(!file.exists()) file.mkdir()
        return path
    }



    fun getDataPath():String{
        return CONTEXT.externalCacheDir!!.path.getBeforeDir()
    }
    companion object{
        val appPath=AppPath()

    }

}


/**
 * https://blog.csdn.net/liuqinhou/article/details/127178594
 * https://www.5axxw.com/questions/content/z1ufap
 * https://blog.csdn.net/weixin_44008788/article/details/123376570
 * https://blog.csdn.net/lplj717/article/details/122811593
 * https://cloud.tencent.com/developer/ask/sof/599903
 * https://www.sunzhongwei.com/registerforactivityresult-startactivityforresultintent-int-unit-is-deprecated-deprecated-in-java
 *
 *
 *
 *
 * 最后用这个
 * https://zhuanlan.zhihu.com/p/268717257
* */